package kode.boot.file.api;

import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Consumer;

/**
 * FileValidator
 * <p>
 * if validation fails, throw FileValidateException
 *
 * @author Administrator
 * @date 2019/1/3
 */
public interface FileValidator extends Consumer<FileMetadata<?>> {

	default boolean parseAsImage() {
		return false;
	}

	default void setParseAsImage(boolean parseAsImage) {
		throw new UnsupportedOperationException();
	}

	default FileValidator andThen(FileValidator after) {
		Objects.requireNonNull(after);

		if (parseAsImage() || after.parseAsImage()) {
			setParseAsImage(true);
		}

		return t -> {
			accept(t);
			after.accept(t);
		};
	}

	/**
	 * validate image width
	 *
	 * @see #HEIGHT
	 */
	Generator<Integer[]> WIDTH = (String message, Integer... range) -> new AbstractFileValidator(true, message) {
		@Override
		public void accept(FileMetadata<?> fileMetadata) {
			validateWidth(fileMetadata, range[0], range[1]);
		}
	};

	/**
	 * validate image height
	 *
	 * @see #WIDTH
	 */
	Generator<Integer[]> HEIGHT = (String message, Integer... range) -> new AbstractFileValidator(true, message) {
		@Override
		public void accept(FileMetadata<?> fileMetadata) {
			validateHeight(fileMetadata, range[0], range[1]);
		}
	};

	/**
	 * validate file size
	 */
	Generator<Long> SIZE = (String message, Long size) -> new AbstractFileValidator(message) {
		@Override
		public void accept(FileMetadata<?> fileMetadata) {
			validateSize(fileMetadata, size);
		}
	};

	/**
	 * validate extension
	 */
	Generator<List<String>> EXTS = (String message, List<String> extList) -> new AbstractFileValidator(message) {
		@Override
		public void accept(FileMetadata<?> fileMetadata) {
			validateExtension(fileMetadata, extList);
		}
	};

	/**
	 * File validator generator
	 *
	 * @param <T> parameter type
	 */
	interface Generator<T> extends BiFunction<String, T, FileValidator> {
	}
}
